package com.example.ff.limage;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import android.os.Environment;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import static android.os.Environment.isExternalStorageRemovable;
import static android.support.constraint.Constraints.TAG;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    private static final int        DISK_CACHE_SIZE = 1024 * 1024 * 16; // 16MB
    private static final String     DISK_CACHE_SUBDIR = "thumbnails";

    private DiskLruCache            mDiskLruCache;
    private BitmapRegionDecoder     mDecoder;
    private BitmapFactory.Options   mOptions;
    private Context                 mContext = InstrumentationRegistry.getTargetContext();
    private String                  mKey = Util.hashKeyForDisk("apple");
    private Bitmap                  mBitmap;

    /*
    @Test
    public void useAppContext() {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.example.ff.limage", appContext.getPackageName());
    }
    */

    private void readFromCache(){
        try {
            DiskLruCache.Snapshot snapshot = mDiskLruCache.get(mKey);
            long begin,end;
            if (snapshot != null) {

                begin = SystemClock.elapsedRealtime();
                InputStream is = snapshot.getInputStream(0);
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                end = SystemClock.elapsedRealtime();

                Log.e(TAG, "readFromCache: load bitmap from cache need " + (end - begin) + " ms." );

                int width = bitmap.getWidth();
                int height = bitmap.getHeight();

                int bitmapByteCount = bitmap.getByteCount();

                Bitmap.Config config = bitmap.getConfig();

                boolean same = mBitmap.sameAs(bitmap);

                Log.e(TAG, "readFromCache : bitmap from cache  width = " + width + " height = " + height + " byte = " + bitmapByteCount
                        + " config = " + config.name() + " sameAs mBitmap = " + same);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    private void saveToCache(){
        try {

            DiskLruCache.Editor editor = mDiskLruCache.edit(mKey);

            if (editor != null){
                OutputStream out = editor.newOutputStream(0);

                InputStream fs = mContext.getAssets().open("world_map.jpg");

                mDecoder = BitmapRegionDecoder.newInstance(fs,false);

                int width = mDecoder.getWidth();
                int height = mDecoder.getHeight();

                mOptions = new BitmapFactory.Options();
                mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
                mOptions.inSampleSize = 8;

                Rect rect = new Rect(0,0,width,height);

                long begin,end;

                begin = SystemClock.elapsedRealtime();
                mBitmap = mDecoder.decodeRegion(rect,mOptions);
                end = SystemClock.elapsedRealtime();

                Log.e(TAG, "pushToCache: decode bitmap need " + (end - begin) + " ms." );

                Log.e(TAG, "readFromCache : mBitmap width = " + mBitmap.getWidth() + " height = " + mBitmap.getHeight() + " byte = " + mBitmap.getByteCount()
                        + " config = " + mOptions.inPreferredConfig.name() );

                mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);

                out.flush();
                editor.commit();
                mDiskLruCache.flush();

                readFromCache();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void testDiskCache() {

        Context context = InstrumentationRegistry.getTargetContext();
        try {

            File cacheDir = context.getCacheDir();

            cacheDir = context.getExternalCacheDir();

            final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !isExternalStorageRemovable()
                    ? context.getExternalCacheDir().getPath()
                    : context.getCacheDir().getPath();
            cacheDir = new File(cachePath + File.separator + DISK_CACHE_SUBDIR);

            PackageManager pm = context.getPackageManager();
            PackageInfo pi = null;
            pi = pm.getPackageInfo(context.getPackageName(), 0);


            int appVersion = pi.versionCode;
            int valueCount = 1;

            mDiskLruCache = DiskLruCache.open(cacheDir, appVersion, valueCount, DISK_CACHE_SIZE);


            saveToCache();

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
